<!DOCTYPE html>
<html lang="" xml:lang="">
<head>

  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Chapter 4 Shiny | JavaScript for R</title>
  <meta name="description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="generator" content="bookdown 0.19 and GitBook 2.6.7" />

  <meta property="og:title" content="Chapter 4 Shiny | JavaScript for R" />
  <meta property="og:type" content="book" />
  
  
  <meta property="og:description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="github-repo" content="yihui/bookdown-crc" />

  <meta name="twitter:card" content="summary" />
  <meta name="twitter:title" content="Chapter 4 Shiny | JavaScript for R" />
  
  <meta name="twitter:description" content="Invite JavaScript into your Data Science workflow." />
  

<meta name="author" content="John Coene" />


<meta name="date" content="2020-06-04" />

  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  
  
<link rel="prev" href="node.html"/>
<link rel="next" href="html-widgets.html"/>
<script src="libs/header-attrs/header-attrs.js"></script>
<script src="libs/jquery/jquery.min.js"></script>
<link href="libs/gitbook/css/style.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-table.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-fontsettings.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-clipboard.css" rel="stylesheet" />









<script src="libs/htmlwidgets/htmlwidgets.js"></script>
<script src="libs/plotly-binding/plotly.js"></script>
<script src="libs/typedarray/typedarray.min.js"></script>
<link href="libs/crosstalk/css/crosstalk.css" rel="stylesheet" />
<script src="libs/crosstalk/js/crosstalk.min.js"></script>
<link href="libs/plotly-htmlwidgets-css/plotly-htmlwidgets.css" rel="stylesheet" />
<script src="libs/plotly-main/plotly-latest.min.js"></script>
<script src="libs/core-js/shim.min.js"></script>
<script src="libs/react/react.min.js"></script>
<script src="libs/react/react-dom.min.js"></script>
<script src="libs/reactwidget/react-tools.js"></script>
<script src="libs/reactable-binding/reactable.js"></script>
<script src="libs/r2d3-render/r2d3-render.js"></script>
<script src="libs/webcomponents/webcomponents.js"></script>
<script src="libs/r2d3-binding/r2d3.js"></script>
<script src="libs/d3v5/d3.min.js"></script>


<style type="text/css">
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code > span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {   }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>

<link rel="stylesheet" href="css/style.css" type="text/css" />
</head>

<body>



  <div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">

    <div class="book-summary">
      <nav role="navigation">

<ul class="summary">
<li><a href="./">R and JavaScript</a></li>

<li class="divider"></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i>Preface</a>
<ul>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#disclaimer"><i class="fa fa-check"></i>Disclaimer</a></li>
</ul></li>
<li class="part"><span><b>I Basics &amp; Roadmap</b></span></li>
<li class="chapter" data-level="1" data-path="introduction.html"><a href="introduction.html"><i class="fa fa-check"></i><b>1</b> Introduction</a>
<ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#rationale"><i class="fa fa-check"></i>Rationale</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#prerequisites"><i class="fa fa-check"></i>Prerequisites</a>
<ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#package-development"><i class="fa fa-check"></i>Package Development</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#json"><i class="fa fa-check"></i>JSON</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#javascript"><i class="fa fa-check"></i>JavaScript</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#methods"><i class="fa fa-check"></i>Methods</a>
<ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#v8"><i class="fa fa-check"></i>V8</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#htmlwidgets"><i class="fa fa-check"></i>htmlwidgets</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#shiny"><i class="fa fa-check"></i>Shiny</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#reactr"><i class="fa fa-check"></i>reactR</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#bubble"><i class="fa fa-check"></i>bubble</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#r2d3"><i class="fa fa-check"></i>r2d3</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>II JavaScript for Computations</b></span></li>
<li class="chapter" data-level="2" data-path="the-v8-engine.html"><a href="the-v8-engine.html"><i class="fa fa-check"></i><b>2</b> The V8 Engine</a>
<ul>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#installation"><i class="fa fa-check"></i>Installation</a></li>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#basics"><i class="fa fa-check"></i>Basics</a></li>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#external-libraries"><i class="fa fa-check"></i>External Libraries</a></li>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#with-npm"><i class="fa fa-check"></i>With Npm</a></li>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#use-in-packages"><i class="fa fa-check"></i>Use in Packages</a></li>
</ul></li>
<li class="chapter" data-level="3" data-path="node.html"><a href="node.html"><i class="fa fa-check"></i><b>3</b> Node.js with Bubble</a>
<ul>
<li class="chapter" data-level="" data-path="node.html"><a href="node.html#basics-1"><i class="fa fa-check"></i>Basics</a></li>
<li class="chapter" data-level="" data-path="node.html"><a href="node.html#r-markdown-engine"><i class="fa fa-check"></i>R Markdown Engine</a></li>
<li class="chapter" data-level="" data-path="node.html"><a href="node.html#npm"><i class="fa fa-check"></i>Npm</a></li>
<li class="chapter" data-level="" data-path="node.html"><a href="node.html#use-in-packages-1"><i class="fa fa-check"></i>Use in Packages</a></li>
</ul></li>
<li class="part"><span><b>III Web Development with Shiny</b></span></li>
<li class="chapter" data-level="4" data-path="shiny-1.html"><a href="shiny-1.html"><i class="fa fa-check"></i><b>4</b> Shiny</a>
<ul>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#static-files"><i class="fa fa-check"></i>Static Files</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#integration"><i class="fa fa-check"></i>Integration</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#from-r-to-javascript"><i class="fa fa-check"></i>From R to JavaScript</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#from-javascript-to-r"><i class="fa fa-check"></i>From JavaScript to R</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#external-library"><i class="fa fa-check"></i>External Library</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#serialisation"><i class="fa fa-check"></i>Serialisation</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#events-callbacks"><i class="fa fa-check"></i>Events &amp; Callbacks</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#as-a-package"><i class="fa fa-check"></i>As a Package</a>
<ul>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#dependencies"><i class="fa fa-check"></i>Dependencies</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#r-code"><i class="fa fa-check"></i>R Code</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#javascript-code"><i class="fa fa-check"></i>JavaScript Code</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#shortcoming"><i class="fa fa-check"></i>Shortcoming</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#input"><i class="fa fa-check"></i>Input</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#wrapping-up"><i class="fa fa-check"></i>Wrapping up</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#exercises"><i class="fa fa-check"></i>Exercises</a></li>
</ul></li>
<li class="part"><span><b>IV Data Visualisation</b></span></li>
<li class="chapter" data-level="5" data-path="html-widgets.html"><a href="html-widgets.html"><i class="fa fa-check"></i><b>5</b> HTML widgets</a>
<ul>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#candidate-libraries"><i class="fa fa-check"></i>Candidate Libraries</a>
<ul>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#plotly"><i class="fa fa-check"></i>Plotly</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#highchart.js"><i class="fa fa-check"></i>Highchart.js</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#chart.js"><i class="fa fa-check"></i>Chart.js</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#how-it-works"><i class="fa fa-check"></i>How it works</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#the-scaffold"><i class="fa fa-check"></i>The Scaffold</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#the-output"><i class="fa fa-check"></i>The Output</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#typed.js"><i class="fa fa-check"></i>Typed.js</a>
<ul>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#dependency"><i class="fa fa-check"></i>Dependency</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#javascript-1"><i class="fa fa-check"></i>JavaScript</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#html-element"><i class="fa fa-check"></i>HTML Element</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#exercises-1"><i class="fa fa-check"></i>Exercises</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#gio.js"><i class="fa fa-check"></i>Gio.js</a>
<ul>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#dependencies-1"><i class="fa fa-check"></i>Dependencies</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#javascript-2"><i class="fa fa-check"></i>JavaScript</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#working-with-data"><i class="fa fa-check"></i>Working with Data</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#transforming-data"><i class="fa fa-check"></i>Transforming Data</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="" data-path="references.html"><a href="references.html"><i class="fa fa-check"></i>References</a></li>
</ul>

      </nav>
    </div>

    <div class="book-body">
      <div class="body-inner">
        <div class="book-header" role="navigation">
          <h1>
            <i class="fa fa-circle-o-notch fa-spin"></i><a href="./">JavaScript for R</a>
          </h1>
        </div>

        <div class="page-wrapper" tabindex="-1" role="main">
          <div class="page-inner">

            <section class="normal" id="section-">
<div id="shiny-1" class="section level1" number="4">
<h1><span class="header-section-number">Chapter 4</span> Shiny</h1>
<p>Shiny is by far most popular, if not the only, web framework for the R programming language. In this chapter, after brushing up on the necessary to include JavaScript in shiny applications, we explore how to blend the JavaScript language with our R server and front-end.</p>
<p>Then again, the aim is not to write a lot of convoluted JavaScript, on the contrary, it is to write as little as possible and demonstrate to the reader that it is often enough to greatly improve the user experience of shiny applications. Making shiny work with JavaScript can essentially be broken down into two operations: 1) passing data from the R server to the JavaScript client and 2) the other way around, from the client to the R server.</p>
<p>In this chapter every section builds upon the previous, only skip those if you truly feel confident you understand it fully or you will get confused.</p>
<div id="static-files" class="section level2 unnumbered" number="">
<h2>Static Files</h2>
<p>In order to introduce JavaScript to shiny applications one must understand static files and how they work with the framework. Static files are files that are downloaded by the clients, in this case web browsers accessing shiny applications, as-is, these generally include images, CSS (<code>.css</code>), and JavaScript (<code>.js</code>).</p>
<p>If you are familiar with R package development, static files are to shiny applications what the “inst” directory is to an R package, those files are installed as-is and do not require further processing as opposed to the “src” folder which contains files that need compiling for instance.</p>
<p>There are numerous ways to run a shiny application locally; the two most used probably are <code>shinyApp</code> and <code>runApp</code>. The RStudio IDE comes with a convenient “Run” button when writing a shiny application, which when clicked actually uses the function <code>shiny::runApp</code> in the background, this function looks for said static files in the <code>www</code> directory and makes them available at the same path (<code>/www</code>). If you are building your applications outside of RStudio, you should either also use <code>shiny::runApp</code> or specify the directory which then allows using <code>shiny::shinyApp</code>. Note that this only applies locally, shiny server (community and pro) as well as <a href="https://www.shinyapps.io/">shinyapps.io</a> use the same defaults as the RStudio IDE and <code>shiny::runApp</code>.</p>
<p>In order to ensure the code in this book can run regardless of the reader’s machine or editor, the asset directory is always specified explicitly. This is probably advised to steer clear of the potential headaches as, unlike the default, it’ll work regardless of the environment. If you are using <a href="https://thinkr-open.github.io/golem/">golem</a> <span class="citation">(Guyader et al. <a href="#ref-R-golem" role="doc-biblioref">2020</a>)</span> to develop your application then you should not worry about this as it specifies the directory internally.</p>
<p>Below we build a basic shiny application, however, before we define the ui and server we use the <code>shiny::addResourcePath</code> function to specify the location of the directory of static files that will be served by the server and thus accessible by the client. This function takes two arguments, first the <code>prefix</code>, which is the path (URL) at which the assets will be available, second the path to the directory of static assets.</p>
<p>We thus create the “assets” directory and a JavaScript file called <code>script.js</code> within it.</p>
<div class="sourceCode" id="cb117"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb117-1"><a href="shiny-1.html#cb117-1"></a><span class="co"># run from root of app (where app.R is located)</span></span>
<span id="cb117-2"><a href="shiny-1.html#cb117-2"></a><span class="kw">dir.create</span>(<span class="st">&quot;assets&quot;</span>)</span>
<span id="cb117-3"><a href="shiny-1.html#cb117-3"></a><span class="kw">writeLines</span>(<span class="st">&quot;console.log(&#39;Hello JS!&#39;);&quot;</span>, <span class="dt">con =</span> <span class="st">&quot;assets/script.js&quot;</span>)</span></code></pre></div>
<p>We can now use the <code>shiny::addResourcePath</code> to point to this directory. Generally the same name for the directory of static assets and prefix is used so as to avoid confusion, below we name them differently in order for the reader to clearly distinguish which is which.</p>
<div class="sourceCode" id="cb118"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb118-1"><a href="shiny-1.html#cb118-1"></a><span class="co"># app.R</span></span>
<span id="cb118-2"><a href="shiny-1.html#cb118-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb118-3"><a href="shiny-1.html#cb118-3"></a></span>
<span id="cb118-4"><a href="shiny-1.html#cb118-4"></a><span class="co"># serve the files</span></span>
<span id="cb118-5"><a href="shiny-1.html#cb118-5"></a><span class="kw">addResourcePath</span>(</span>
<span id="cb118-6"><a href="shiny-1.html#cb118-6"></a>  <span class="co"># will be accessible at /files</span></span>
<span id="cb118-7"><a href="shiny-1.html#cb118-7"></a>  <span class="dt">prefix =</span> <span class="st">&quot;files&quot;</span>, </span>
<span id="cb118-8"><a href="shiny-1.html#cb118-8"></a>  <span class="co"># path to our assets directory</span></span>
<span id="cb118-9"><a href="shiny-1.html#cb118-9"></a>  <span class="dt">directoryPath =</span> <span class="st">&quot;assets&quot;</span></span>
<span id="cb118-10"><a href="shiny-1.html#cb118-10"></a>)</span>
<span id="cb118-11"><a href="shiny-1.html#cb118-11"></a></span>
<span id="cb118-12"><a href="shiny-1.html#cb118-12"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb118-13"><a href="shiny-1.html#cb118-13"></a>  <span class="kw">h1</span>(<span class="st">&quot;R and JavaScript&quot;</span>)</span>
<span id="cb118-14"><a href="shiny-1.html#cb118-14"></a>)</span>
<span id="cb118-15"><a href="shiny-1.html#cb118-15"></a></span>
<span id="cb118-16"><a href="shiny-1.html#cb118-16"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output){}</span>
<span id="cb118-17"><a href="shiny-1.html#cb118-17"></a></span>
<span id="cb118-18"><a href="shiny-1.html#cb118-18"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<p>If you then run the application and open it at the <code>/files/script.js</code> path (e.g.: <code>127.0.0.1:3000/files/script.js</code>) you should see the content of our JavaScript file (<code>console.log('Hello JS!')</code>), commenting the <code>addResourcePath</code> line will have a “Not Found” error displayed on the page instead.</p>
<p>All files in your asset directory will be served online and accessible to anyone: do not place sensitive files in it.</p>
<p>Though one may create multiple such directory and correspondingly use <code>addResourcePath</code> to specify multiple paths and prefixes, one will routinely specify a single one, named “assets” or “static,” which contains multiple subdirectories, one for each type of static file to obtain a directory that looks something like the tree below. This is, however, an unwritten convention which is by no means forced upon the developer: do as you wish.</p>
<pre><code>assets/
├── js/
│    └── script.js
├── css/
│    └── style.css
└── img/
     └── pic.png</code></pre>
<p>At this stage we have made the JavaScript file we created accessible by the clients but we still have to source this file in our <code>ui</code> as currently this file is, though served, not used by our application. Were one creating a static HTML page one would use the <code>script</code> to <code>src</code> the file in the <code>head</code> of the page.</p>
<div class="sourceCode" id="cb120"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb120-1"><a href="shiny-1.html#cb120-1"></a><span class="kw">&lt;html&gt;</span></span>
<span id="cb120-2"><a href="shiny-1.html#cb120-2"></a>  <span class="kw">&lt;head&gt;</span></span>
<span id="cb120-3"><a href="shiny-1.html#cb120-3"></a>    <span class="er">&lt;</span>!–– source the JavaScript file ––&gt;</span>
<span id="cb120-4"><a href="shiny-1.html#cb120-4"></a>    <span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;path/to/script.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb120-5"><a href="shiny-1.html#cb120-5"></a>  <span class="kw">&lt;/head&gt;</span></span>
<span id="cb120-6"><a href="shiny-1.html#cb120-6"></a>  <span class="kw">&lt;body&gt;</span></span>
<span id="cb120-7"><a href="shiny-1.html#cb120-7"></a>    <span class="kw">&lt;p</span><span class="ot"> id=</span><span class="st">&quot;content&quot;</span><span class="kw">&gt;</span>Trying JavaScript!<span class="kw">&lt;/p&gt;</span></span>
<span id="cb120-8"><a href="shiny-1.html#cb120-8"></a>  <span class="kw">&lt;/body&gt;</span></span>
<span id="cb120-9"><a href="shiny-1.html#cb120-9"></a><span class="kw">&lt;/html&gt;</span></span></code></pre></div>
<p>In shiny we write the ui in R and not in HTML (though this is also supported). Given the resemblance between the names of HTML tags and shiny UI functions it’s pretty straightforward, the html page above would look something like the shiny <code>ui</code> below.</p>
<div class="sourceCode" id="cb121"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb121-1"><a href="shiny-1.html#cb121-1"></a><span class="kw">library</span>(shiny)</span>
<span id="cb121-2"><a href="shiny-1.html#cb121-2"></a></span>
<span id="cb121-3"><a href="shiny-1.html#cb121-3"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb121-4"><a href="shiny-1.html#cb121-4"></a>  tags<span class="op">$</span><span class="kw">head</span>(</span>
<span id="cb121-5"><a href="shiny-1.html#cb121-5"></a>    tags<span class="op">$</span><span class="kw">script</span>(<span class="dt">src =</span> <span class="st">&quot;path/to/script.js&quot;</span>)</span>
<span id="cb121-6"><a href="shiny-1.html#cb121-6"></a>  ),</span>
<span id="cb121-7"><a href="shiny-1.html#cb121-7"></a>  <span class="kw">p</span>(<span class="dt">id =</span> <span class="st">&quot;content&quot;</span>, <span class="st">&quot;Trying JavaScript!&quot;</span>)</span>
<span id="cb121-8"><a href="shiny-1.html#cb121-8"></a>)</span></code></pre></div>
<p>Note that we use the <code>tags</code> object which comes from the shiny package and includes HTML tags that are not exported as standalone functions. For instance, you can create a <code>&lt;div&gt;</code> in shiny with the <code>div</code> function but <code>tags$div</code> will also work. This can now be applied to the shiny application, the <code>path/to/script.js</code> should be changed to <code>files/script.js</code> where <code>files</code> is the prefix we defined in <code>addResourcePath</code>.</p>
<div class="sourceCode" id="cb122"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb122-1"><a href="shiny-1.html#cb122-1"></a><span class="co"># app.R</span></span>
<span id="cb122-2"><a href="shiny-1.html#cb122-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb122-3"><a href="shiny-1.html#cb122-3"></a></span>
<span id="cb122-4"><a href="shiny-1.html#cb122-4"></a><span class="co"># serve the files</span></span>
<span id="cb122-5"><a href="shiny-1.html#cb122-5"></a><span class="kw">addResourcePath</span>(<span class="dt">prefix =</span> <span class="st">&quot;files&quot;</span>, <span class="dt">directoryPath =</span> <span class="st">&quot;assets&quot;</span>)</span>
<span id="cb122-6"><a href="shiny-1.html#cb122-6"></a></span>
<span id="cb122-7"><a href="shiny-1.html#cb122-7"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb122-8"><a href="shiny-1.html#cb122-8"></a>  tags<span class="op">$</span><span class="kw">head</span>(</span>
<span id="cb122-9"><a href="shiny-1.html#cb122-9"></a>    tags<span class="op">$</span><span class="kw">script</span>(<span class="dt">src =</span> <span class="st">&quot;files/script.js&quot;</span>)</span>
<span id="cb122-10"><a href="shiny-1.html#cb122-10"></a>  ),</span>
<span id="cb122-11"><a href="shiny-1.html#cb122-11"></a>  <span class="kw">h1</span>(<span class="st">&quot;R and JavaScript&quot;</span>)</span>
<span id="cb122-12"><a href="shiny-1.html#cb122-12"></a>)</span>
<span id="cb122-13"><a href="shiny-1.html#cb122-13"></a></span>
<span id="cb122-14"><a href="shiny-1.html#cb122-14"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output){}</span>
<span id="cb122-15"><a href="shiny-1.html#cb122-15"></a></span>
<span id="cb122-16"><a href="shiny-1.html#cb122-16"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<p>From the browser, inspecting page (right click &gt; inspect &gt; console tab) one should see “Hello JS!” in the console which means our application correctly ran the code in our JavaScript file.</p>
</div>
<div id="integration" class="section level2 unnumbered" number="">
<h2>Integration</h2>
<p>The following sections will walk you through an example in which one first starts with a basic hello-world-like JavaScript example running in shiny and ends with a fully-fledged R package that brings new functionalities to shiny by integrating a third party library.</p>
<p>We first build an application that passes a message from the R server to the client to display said message as a vanilla JavaScript alert (pop-up), then send back to the R server whether the user has clicked “OK” on the alert. Finally we replicate that but with an external library and wrap the whole project into a fully functional package. This package will look similar to others that provide JavaScript integrations with shiny such as shinyjs <span class="citation">(Attali <a href="#ref-R-shinyjs" role="doc-biblioref">2020</a>)</span> or waiter <span class="citation">(Coene <a href="#ref-R-waiter" role="doc-biblioref">2020</a>)</span>.</p>
<p>First, let’s write a barebone shiny application which includes the JavaScript code which opens an alert.</p>
<div class="sourceCode" id="cb123"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb123-1"><a href="shiny-1.html#cb123-1"></a><span class="kw">library</span>(shiny)</span>
<span id="cb123-2"><a href="shiny-1.html#cb123-2"></a></span>
<span id="cb123-3"><a href="shiny-1.html#cb123-3"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb123-4"><a href="shiny-1.html#cb123-4"></a>  tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb123-5"><a href="shiny-1.html#cb123-5"></a>    <span class="st">&quot;alert(&#39;Hello from JavaScript&#39;);&quot;</span></span>
<span id="cb123-6"><a href="shiny-1.html#cb123-6"></a>  ),</span>
<span id="cb123-7"><a href="shiny-1.html#cb123-7"></a>  <span class="kw">h1</span>(<span class="st">&quot;Hello&quot;</span>)</span>
<span id="cb123-8"><a href="shiny-1.html#cb123-8"></a>)</span>
<span id="cb123-9"><a href="shiny-1.html#cb123-9"></a></span>
<span id="cb123-10"><a href="shiny-1.html#cb123-10"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session){}</span>
<span id="cb123-11"><a href="shiny-1.html#cb123-11"></a></span>
<span id="cb123-12"><a href="shiny-1.html#cb123-12"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<div class="figure">
<img src="images/alert.png" alt="" />
<p class="caption">JavaScript alert in shiny</p>
</div>
<p>One thing important to note for later is that alerts will always block the execution of code which allows making sure some code is only run with user consent or the user being aware of the consequences.</p>
<div class="sourceCode" id="cb124"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb124-1"><a href="shiny-1.html#cb124-1"></a><span class="at">alert</span>(<span class="st">&#39;delete everything?&#39;</span>)<span class="op">;</span></span>
<span id="cb124-2"><a href="shiny-1.html#cb124-2"></a><span class="at">deleteEverythingOnlyIfUserOK</span>()<span class="op">;</span></span></code></pre></div>
</div>
<div id="from-r-to-javascript" class="section level2 unnumbered" number="">
<h2>From R to JavaScript</h2>
<p>Now that we have a simple alert displayed in the application we can tie it with our R server; the alert should display a message sent by the R server, this would enable, for instance, displaying a message taken from a database or a user input. As might be expected there are two functions required to do so, an R function and its JavaScript complementary: one to send the data from the server and another to catch said data from the client and display the alert.</p>
<p>Let us start by writing the R code to send the data, thankfully very little is required of the developer. One can send data from the R server to the client from the <code>session</code> object using the <code>sendCustomMessage</code> method. The method takes two arguments, first an identifier (where to send the data to), second the actual data to send to JavaScript.</p>
<div class="sourceCode" id="cb125"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb125-1"><a href="shiny-1.html#cb125-1"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session){</span>
<span id="cb125-2"><a href="shiny-1.html#cb125-2"></a>  <span class="co"># set the identifier to send-alert</span></span>
<span id="cb125-3"><a href="shiny-1.html#cb125-3"></a>  session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="dt">type =</span> <span class="st">&quot;send-alert&quot;</span>, <span class="dt">message =</span> <span class="st">&quot;Hi there!&quot;</span>)</span>
<span id="cb125-4"><a href="shiny-1.html#cb125-4"></a>}</span></code></pre></div>
<p>This effectively sends our message to the JavaScript client but we are yet to use that message JavaScript-side so the application still displays the same alert on load. We can add a “handler” for the identifier we defined (<code>send-alert</code>) which will so something with the message we sent from the server. This is done with the <code>addCustomMessageHandler</code> method from the <code>Shiny</code> object where the first argument is the identifier and the second is the function that handles the message, generally a function that takes a single argument: the data sent from the server.</p>
<div class="sourceCode" id="cb126"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb126-1"><a href="shiny-1.html#cb126-1"></a>tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb126-2"><a href="shiny-1.html#cb126-2"></a>  <span class="st">&quot;Shiny.addCustomMessageHandler(type = &#39;send-alert&#39;, function(message) {</span></span>
<span id="cb126-3"><a href="shiny-1.html#cb126-3"></a><span class="st">    alert(message);</span></span>
<span id="cb126-4"><a href="shiny-1.html#cb126-4"></a><span class="st">  });&quot;</span></span>
<span id="cb126-5"><a href="shiny-1.html#cb126-5"></a>)</span></code></pre></div>
<div class="figure">
<img src="images/alert-shiny.png" alt="" />
<p class="caption">Alert sent from shiny server</p>
</div>
<p>This enables you to pass a message that is taken from a database for instance, or as shown below from a user input, to the alert.</p>
<div class="sourceCode" id="cb127"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb127-1"><a href="shiny-1.html#cb127-1"></a><span class="kw">library</span>(shiny)</span>
<span id="cb127-2"><a href="shiny-1.html#cb127-2"></a></span>
<span id="cb127-3"><a href="shiny-1.html#cb127-3"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb127-4"><a href="shiny-1.html#cb127-4"></a>  tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb127-5"><a href="shiny-1.html#cb127-5"></a>    <span class="st">&quot;Shiny.addCustomMessageHandler(type = &#39;send-alert&#39;, function(message) {</span></span>
<span id="cb127-6"><a href="shiny-1.html#cb127-6"></a><span class="st">      alert(message);</span></span>
<span id="cb127-7"><a href="shiny-1.html#cb127-7"></a><span class="st">    });&quot;</span></span>
<span id="cb127-8"><a href="shiny-1.html#cb127-8"></a>  ),</span>
<span id="cb127-9"><a href="shiny-1.html#cb127-9"></a>  <span class="kw">h1</span>(<span class="st">&quot;Hello&quot;</span>),</span>
<span id="cb127-10"><a href="shiny-1.html#cb127-10"></a>  <span class="kw">textInput</span>(<span class="st">&quot;text&quot;</span>, <span class="st">&quot;Text to show in alert&quot;</span>),</span>
<span id="cb127-11"><a href="shiny-1.html#cb127-11"></a>  <span class="kw">actionButton</span>(<span class="st">&quot;submit&quot;</span>, <span class="st">&quot;Show alert&quot;</span>)</span>
<span id="cb127-12"><a href="shiny-1.html#cb127-12"></a>)</span>
<span id="cb127-13"><a href="shiny-1.html#cb127-13"></a></span>
<span id="cb127-14"><a href="shiny-1.html#cb127-14"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session){</span>
<span id="cb127-15"><a href="shiny-1.html#cb127-15"></a>  <span class="kw">observeEvent</span>(input<span class="op">$</span>submit, {</span>
<span id="cb127-16"><a href="shiny-1.html#cb127-16"></a>    session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="dt">type =</span> <span class="st">&quot;send-alert&quot;</span>, <span class="dt">message =</span> input<span class="op">$</span>text)</span>
<span id="cb127-17"><a href="shiny-1.html#cb127-17"></a>  })</span>
<span id="cb127-18"><a href="shiny-1.html#cb127-18"></a>}</span>
<span id="cb127-19"><a href="shiny-1.html#cb127-19"></a></span>
<span id="cb127-20"><a href="shiny-1.html#cb127-20"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<p>In the application above, notice the path that our message follows: it goes from the client to the server which sends it back to the client. This might be considered suboptimal by some as it is not necessary to use the server as intermediary (in this example at least). Though there is some truth to this the above will work perfectly fine—and our aim here is to make JavaScript work with R—not alongside it.</p>
</div>
<div id="from-javascript-to-r" class="section level2 unnumbered" number="">
<h2>From JavaScript to R</h2>
<p>Imagine if you will that instead of displaying a somewhat anodyne alert it was one that actually mattered where the user is warned that clicking “OK” will execute an irreversible action like the deletion of a record. In order to implement this the server would need to “know” whether the user has clicked said “OK” button. To do so one needs to pass data from the client to the server.</p>
<p>This can be done by defining a new <em>simplified</em> shiny input. While one can define a fully-fledged shiny input that can be registered, updated, etc. there is also a simplified version of the latter which allows sending reactive input value to the server where it can be used just like any other inputs (<code>input$id</code>). The value of the input can be defined using the <code>setInputValue</code> method which takes the id of the input and the value to give it.</p>
<div class="sourceCode" id="cb128"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb128-1"><a href="shiny-1.html#cb128-1"></a>tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb128-2"><a href="shiny-1.html#cb128-2"></a>  <span class="st">&quot;Shiny.addCustomMessageHandler(type = &#39;send-alert&#39;, function(message) {</span></span>
<span id="cb128-3"><a href="shiny-1.html#cb128-3"></a><span class="st">    </span></span>
<span id="cb128-4"><a href="shiny-1.html#cb128-4"></a><span class="st">    // show alert</span></span>
<span id="cb128-5"><a href="shiny-1.html#cb128-5"></a><span class="st">    alert(message);</span></span>
<span id="cb128-6"><a href="shiny-1.html#cb128-6"></a></span>
<span id="cb128-7"><a href="shiny-1.html#cb128-7"></a><span class="st">    // set to true when clicked OK</span></span>
<span id="cb128-8"><a href="shiny-1.html#cb128-8"></a><span class="st">    Shiny.setInputValue(&#39;delete_alert&#39;, true);</span></span>
<span id="cb128-9"><a href="shiny-1.html#cb128-9"></a><span class="st">  });&quot;</span></span>
<span id="cb128-10"><a href="shiny-1.html#cb128-10"></a>)</span></code></pre></div>
<p>As mentioned earlier <code>alert</code> blocks code execution, therefore the input value will not be defined before the button “OK” is pressed. The server can now access the <code>input$delete_alert</code> input which is by default <code>NULL</code> and set to <code>TRUE</code> when the user has pressed “OK,” as done in the application below which prints the input to the console when the button is clicked.</p>
<div class="sourceCode" id="cb129"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb129-1"><a href="shiny-1.html#cb129-1"></a><span class="kw">library</span>(shiny)</span>
<span id="cb129-2"><a href="shiny-1.html#cb129-2"></a></span>
<span id="cb129-3"><a href="shiny-1.html#cb129-3"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb129-4"><a href="shiny-1.html#cb129-4"></a>  tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb129-5"><a href="shiny-1.html#cb129-5"></a>    <span class="st">&quot;Shiny.addCustomMessageHandler(type = &#39;send-alert&#39;, function(message) {</span></span>
<span id="cb129-6"><a href="shiny-1.html#cb129-6"></a><span class="st">      alert(message);</span></span>
<span id="cb129-7"><a href="shiny-1.html#cb129-7"></a><span class="st">      Shiny.setInputValue(&#39;delete_alert&#39;, true);</span></span>
<span id="cb129-8"><a href="shiny-1.html#cb129-8"></a><span class="st">    });&quot;</span></span>
<span id="cb129-9"><a href="shiny-1.html#cb129-9"></a>  ),</span>
<span id="cb129-10"><a href="shiny-1.html#cb129-10"></a>  <span class="kw">h1</span>(<span class="st">&quot;Hello&quot;</span>)</span>
<span id="cb129-11"><a href="shiny-1.html#cb129-11"></a>)</span>
<span id="cb129-12"><a href="shiny-1.html#cb129-12"></a></span>
<span id="cb129-13"><a href="shiny-1.html#cb129-13"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session){</span>
<span id="cb129-14"><a href="shiny-1.html#cb129-14"></a>  session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="dt">type =</span> <span class="st">&quot;send-alert&quot;</span>, <span class="dt">message =</span> <span class="st">&quot;Deleting a record!&quot;</span>)</span>
<span id="cb129-15"><a href="shiny-1.html#cb129-15"></a></span>
<span id="cb129-16"><a href="shiny-1.html#cb129-16"></a>  <span class="kw">observeEvent</span>(input<span class="op">$</span>delete_alert, {</span>
<span id="cb129-17"><a href="shiny-1.html#cb129-17"></a>    <span class="co"># print TRUE when button is clicked</span></span>
<span id="cb129-18"><a href="shiny-1.html#cb129-18"></a>    <span class="kw">print</span>(input<span class="op">$</span>delete_alert) </span>
<span id="cb129-19"><a href="shiny-1.html#cb129-19"></a>  })</span>
<span id="cb129-20"><a href="shiny-1.html#cb129-20"></a>}</span>
<span id="cb129-21"><a href="shiny-1.html#cb129-21"></a></span>
<span id="cb129-22"><a href="shiny-1.html#cb129-22"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
</div>
<div id="external-library" class="section level2 unnumbered" number="">
<h2>External Library</h2>
<p>Thus far this chapter has covered both ways data travels between JavaScript and R in Shiny. However, the alerts displayed in the previous sections are rather hideous and, though demonstrates how both languages can work together within shiny, comes short of illustrating how to make use of external libraries, which is frequently performed as one progressively learn a language.</p>
<p>Let’s exploit an external library to improve upon the work done so far: <a href="https://github.com/StephanWagner/jBox">jBox</a> allows displaying modals (pop-ups), very similar to the vanilla JavaScript alerts, but much better looking and with additional functionalities.</p>
<p>The very first thing to do is to import jBox in our project, we could download the files and use them as described in the previous static files section but it comes with very convenient CDNs detailed in the <a href="https://stephanwagner.me/jBox/get_started">get-started page of the documentation</a>.</p>
<div class="sourceCode" id="cb130"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb130-1"><a href="shiny-1.html#cb130-1"></a><span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;https://code.jquery.com/jquery-3.5.1.min.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb130-2"><a href="shiny-1.html#cb130-2"></a><span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;https://cdn.jsdelivr.net/gh/StephanWagner/jBox@v1.2.0/dist/jBox.all.min.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb130-3"><a href="shiny-1.html#cb130-3"></a><span class="kw">&lt;link</span><span class="ot"> href=</span><span class="st">&quot;https://cdn.jsdelivr.net/gh/StephanWagner/jBox@v1.2.0/dist/jBox.all.min.css&quot;</span><span class="ot"> rel=</span><span class="st">&quot;stylesheet&quot;</span><span class="kw">&gt;</span></span></code></pre></div>
<p>Note that the “j” in jBox stands for jQuery which is already a dependency of shiny itself, there is therefore no need to import it, on the contrary one should not in order to avoid clashes. We can adapt the ui of the shiny application built up to this point to import the dependencies, keeping the handler, to obtain the code below.</p>
<div class="sourceCode" id="cb131"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb131-1"><a href="shiny-1.html#cb131-1"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb131-2"><a href="shiny-1.html#cb131-2"></a>  tags<span class="op">$</span><span class="kw">head</span>(</span>
<span id="cb131-3"><a href="shiny-1.html#cb131-3"></a>    tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb131-4"><a href="shiny-1.html#cb131-4"></a>      <span class="dt">src =</span> <span class="st">&quot;https://cdn.jsdelivr.net/gh/StephanWagner/jBox@v1.2.0/dist/jBox.all.min.js&quot;</span></span>
<span id="cb131-5"><a href="shiny-1.html#cb131-5"></a>    ),</span>
<span id="cb131-6"><a href="shiny-1.html#cb131-6"></a>    tags<span class="op">$</span><span class="kw">link</span>(</span>
<span id="cb131-7"><a href="shiny-1.html#cb131-7"></a>      <span class="dt">rel =</span> <span class="st">&quot;stylesheet&quot;</span>,</span>
<span id="cb131-8"><a href="shiny-1.html#cb131-8"></a>      <span class="dt">href =</span> <span class="st">&quot;https://cdn.jsdelivr.net/gh/StephanWagner/jBox@v1.2.0/dist/jBox.all.min.css&quot;</span></span>
<span id="cb131-9"><a href="shiny-1.html#cb131-9"></a>    ),</span>
<span id="cb131-10"><a href="shiny-1.html#cb131-10"></a>    tags<span class="op">$</span><span class="kw">script</span>(<span class="st">&quot;Shiny.addCustomMessageHandler(type = &#39;send-alert&#39;, function(message) {</span></span>
<span id="cb131-11"><a href="shiny-1.html#cb131-11"></a><span class="st">      // TO DO: code jBox</span></span>
<span id="cb131-12"><a href="shiny-1.html#cb131-12"></a><span class="st">    });&quot;</span>)</span>
<span id="cb131-13"><a href="shiny-1.html#cb131-13"></a>  )</span>
<span id="cb131-14"><a href="shiny-1.html#cb131-14"></a>)</span></code></pre></div>
<p>The jBox library comes with numerous features to display tooltips, modals, notices, and more, which would make for too long a chapter; only notices shall be covered here. Further down the <a href="https://stephanwagner.me/jBox/get_started#notices">get-started document</a> lies an example of a jBox notice.</p>
<div class="sourceCode" id="cb132"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb132-1"><a href="shiny-1.html#cb132-1"></a><span class="kw">new</span> <span class="at">jBox</span>(<span class="st">&#39;Notice&#39;</span><span class="op">,</span> <span class="op">{</span></span>
<span id="cb132-2"><a href="shiny-1.html#cb132-2"></a>  <span class="dt">content</span><span class="op">:</span> <span class="st">&#39;Hurray! A notice!&#39;</span><span class="op">,</span></span>
<span id="cb132-3"><a href="shiny-1.html#cb132-3"></a>  <span class="dt">color</span><span class="op">:</span> <span class="st">&#39;blue&#39;</span></span>
<span id="cb132-4"><a href="shiny-1.html#cb132-4"></a><span class="op">}</span>)<span class="op">;</span></span></code></pre></div>
<p>Let us copy that in the placeholder of the shiny ui already put together.</p>
<div class="sourceCode" id="cb133"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb133-1"><a href="shiny-1.html#cb133-1"></a><span class="kw">library</span>(shiny)</span>
<span id="cb133-2"><a href="shiny-1.html#cb133-2"></a></span>
<span id="cb133-3"><a href="shiny-1.html#cb133-3"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb133-4"><a href="shiny-1.html#cb133-4"></a>  tags<span class="op">$</span><span class="kw">head</span>(</span>
<span id="cb133-5"><a href="shiny-1.html#cb133-5"></a>    tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb133-6"><a href="shiny-1.html#cb133-6"></a>      <span class="dt">src =</span> <span class="st">&quot;https://cdn.jsdelivr.net/gh/StephanWagner/jBox@v1.2.0/dist/jBox.all.min.js&quot;</span></span>
<span id="cb133-7"><a href="shiny-1.html#cb133-7"></a>    ),</span>
<span id="cb133-8"><a href="shiny-1.html#cb133-8"></a>    tags<span class="op">$</span><span class="kw">link</span>(</span>
<span id="cb133-9"><a href="shiny-1.html#cb133-9"></a>      <span class="dt">rel =</span> <span class="st">&quot;stylesheet&quot;</span>,</span>
<span id="cb133-10"><a href="shiny-1.html#cb133-10"></a>      <span class="dt">href =</span> <span class="st">&quot;https://cdn.jsdelivr.net/gh/StephanWagner/jBox@v1.2.0/dist/jBox.all.min.css&quot;</span></span>
<span id="cb133-11"><a href="shiny-1.html#cb133-11"></a>    ),</span>
<span id="cb133-12"><a href="shiny-1.html#cb133-12"></a>    tags<span class="op">$</span><span class="kw">script</span>(<span class="st">&quot;Shiny.addCustomMessageHandler(type = &#39;send-alert&#39;, function(message) {</span></span>
<span id="cb133-13"><a href="shiny-1.html#cb133-13"></a><span class="st">      new jBox(&#39;Notice&#39;, {</span></span>
<span id="cb133-14"><a href="shiny-1.html#cb133-14"></a><span class="st">        content: &#39;Hurray! A notice!&#39;,</span></span>
<span id="cb133-15"><a href="shiny-1.html#cb133-15"></a><span class="st">        color: &#39;blue&#39;</span></span>
<span id="cb133-16"><a href="shiny-1.html#cb133-16"></a><span class="st">      });</span></span>
<span id="cb133-17"><a href="shiny-1.html#cb133-17"></a><span class="st">    });&quot;</span>)</span>
<span id="cb133-18"><a href="shiny-1.html#cb133-18"></a>  )</span>
<span id="cb133-19"><a href="shiny-1.html#cb133-19"></a>)</span>
<span id="cb133-20"><a href="shiny-1.html#cb133-20"></a></span>
<span id="cb133-21"><a href="shiny-1.html#cb133-21"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session){</span>
<span id="cb133-22"><a href="shiny-1.html#cb133-22"></a>  session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="dt">type =</span> <span class="st">&quot;send-alert&quot;</span>, <span class="dt">message =</span> <span class="st">&quot;Deleting a record!&quot;</span>)</span>
<span id="cb133-23"><a href="shiny-1.html#cb133-23"></a>}</span>
<span id="cb133-24"><a href="shiny-1.html#cb133-24"></a></span>
<span id="cb133-25"><a href="shiny-1.html#cb133-25"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<div class="figure">
<img src="images/notice-1.png" alt="" />
<p class="caption">First jBox Notice</p>
</div>
<p>With some minor changes the application can display the message passed, one only needs to replace ‘Hurray! A notice!’ with the <code>message</code> variable.</p>
<div class="sourceCode" id="cb134"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb134-1"><a href="shiny-1.html#cb134-1"></a>tags<span class="op">$</span><span class="kw">script</span>(<span class="st">&quot;Shiny.addCustomMessageHandler(type = &#39;send-alert&#39;, function(message) {</span></span>
<span id="cb134-2"><a href="shiny-1.html#cb134-2"></a><span class="st">  new jBox(&#39;Notice&#39;, {</span></span>
<span id="cb134-3"><a href="shiny-1.html#cb134-3"></a><span class="st">    content: message,</span></span>
<span id="cb134-4"><a href="shiny-1.html#cb134-4"></a><span class="st">    color: &#39;blue&#39;</span></span>
<span id="cb134-5"><a href="shiny-1.html#cb134-5"></a><span class="st">  });</span></span>
<span id="cb134-6"><a href="shiny-1.html#cb134-6"></a><span class="st">});&quot;</span>)</span></code></pre></div>
<p>This though only allows passing a single variable, the message, to JavaScript but jBox has many more options.</p>
</div>
<div id="serialisation" class="section level2 unnumbered" number="">
<h2>Serialisation</h2>
<p>Let’s delve deeper into the communication between the server and the front-end to understand how we can further customise the notice displayed, e.g.: change the colour.</p>
<div class="sourceCode" id="cb135"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb135-1"><a href="shiny-1.html#cb135-1"></a><span class="op">{</span></span>
<span id="cb135-2"><a href="shiny-1.html#cb135-2"></a>  <span class="dt">content</span><span class="op">:</span> <span class="st">&#39;Hurray! A notice!&#39;</span><span class="op">,</span></span>
<span id="cb135-3"><a href="shiny-1.html#cb135-3"></a>  <span class="dt">color</span><span class="op">:</span> <span class="st">&#39;blue&#39;</span></span>
<span id="cb135-4"><a href="shiny-1.html#cb135-4"></a><span class="op">}</span></span></code></pre></div>
<p>Notice that the jBox notice takes a JSON object containing the options that define said notice to display, including but not limited to the message. The most straightforward way to make all those options accessible to the server is to construct that list of options server-side before sending it to the the front-end. For instance the JSON of options displayed above would look like the R list below.</p>
<div class="sourceCode" id="cb136"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb136-1"><a href="shiny-1.html#cb136-1"></a><span class="kw">list</span>(</span>
<span id="cb136-2"><a href="shiny-1.html#cb136-2"></a>  <span class="dt">content =</span> <span class="st">&#39;Hurray! A notice!&#39;</span>,</span>
<span id="cb136-3"><a href="shiny-1.html#cb136-3"></a>  <span class="dt">color =</span> <span class="st">&#39;blue&#39;</span></span>
<span id="cb136-4"><a href="shiny-1.html#cb136-4"></a>)</span></code></pre></div>
<p>Therefore one could construct this list server-side and use it in jBox straight away, without any further processing from the client. Doing so means we can simplify the JavaScript to <code>new jBox('Notice', message);</code> rather than use <code>message</code> within the JSON.</p>
<div class="sourceCode" id="cb137"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb137-1"><a href="shiny-1.html#cb137-1"></a><span class="kw">library</span>(shiny)</span>
<span id="cb137-2"><a href="shiny-1.html#cb137-2"></a></span>
<span id="cb137-3"><a href="shiny-1.html#cb137-3"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb137-4"><a href="shiny-1.html#cb137-4"></a>  tags<span class="op">$</span><span class="kw">head</span>(</span>
<span id="cb137-5"><a href="shiny-1.html#cb137-5"></a>    tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb137-6"><a href="shiny-1.html#cb137-6"></a>      <span class="dt">src =</span> <span class="st">&quot;https://cdn.jsdelivr.net/gh/StephanWagner/jBox@v1.2.0/dist/jBox.all.min.js&quot;</span></span>
<span id="cb137-7"><a href="shiny-1.html#cb137-7"></a>    ),</span>
<span id="cb137-8"><a href="shiny-1.html#cb137-8"></a>    tags<span class="op">$</span><span class="kw">link</span>(</span>
<span id="cb137-9"><a href="shiny-1.html#cb137-9"></a>      <span class="dt">rel =</span> <span class="st">&quot;stylesheet&quot;</span>,</span>
<span id="cb137-10"><a href="shiny-1.html#cb137-10"></a>      <span class="dt">href =</span> <span class="st">&quot;https://cdn.jsdelivr.net/gh/StephanWagner/jBox@v1.2.0/dist/jBox.all.min.css&quot;</span></span>
<span id="cb137-11"><a href="shiny-1.html#cb137-11"></a>    ),</span>
<span id="cb137-12"><a href="shiny-1.html#cb137-12"></a>    tags<span class="op">$</span><span class="kw">script</span>(<span class="st">&quot;Shiny.addCustomMessageHandler(type = &#39;send-alert&#39;, function(message) {</span></span>
<span id="cb137-13"><a href="shiny-1.html#cb137-13"></a><span class="st">      // use notice send from the server</span></span>
<span id="cb137-14"><a href="shiny-1.html#cb137-14"></a><span class="st">      new jBox(&#39;Notice&#39;, message);</span></span>
<span id="cb137-15"><a href="shiny-1.html#cb137-15"></a><span class="st">    });&quot;</span>)</span>
<span id="cb137-16"><a href="shiny-1.html#cb137-16"></a>  )</span>
<span id="cb137-17"><a href="shiny-1.html#cb137-17"></a>)</span>
<span id="cb137-18"><a href="shiny-1.html#cb137-18"></a></span>
<span id="cb137-19"><a href="shiny-1.html#cb137-19"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session){</span>
<span id="cb137-20"><a href="shiny-1.html#cb137-20"></a></span>
<span id="cb137-21"><a href="shiny-1.html#cb137-21"></a>  <span class="co"># define notice options</span></span>
<span id="cb137-22"><a href="shiny-1.html#cb137-22"></a>  notice =<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb137-23"><a href="shiny-1.html#cb137-23"></a>    <span class="dt">content =</span> <span class="st">&#39;Hello from the server&#39;</span>,</span>
<span id="cb137-24"><a href="shiny-1.html#cb137-24"></a>    <span class="dt">color =</span> <span class="st">&#39;black&#39;</span></span>
<span id="cb137-25"><a href="shiny-1.html#cb137-25"></a>  )</span>
<span id="cb137-26"><a href="shiny-1.html#cb137-26"></a></span>
<span id="cb137-27"><a href="shiny-1.html#cb137-27"></a>  <span class="co"># send the notice</span></span>
<span id="cb137-28"><a href="shiny-1.html#cb137-28"></a>  session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="dt">type =</span> <span class="st">&quot;send-alert&quot;</span>, <span class="dt">message =</span> notice)</span>
<span id="cb137-29"><a href="shiny-1.html#cb137-29"></a>}</span>
<span id="cb137-30"><a href="shiny-1.html#cb137-30"></a></span>
<span id="cb137-31"><a href="shiny-1.html#cb137-31"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<div class="figure">
<img src="images/notice-2.png" alt="" />
<p class="caption">Customised jBox Notice</p>
</div>
<p>This sets a solid basis to further integrate other functionalities of jBox.</p>
</div>
<div id="events-callbacks" class="section level2 unnumbered" number="">
<h2>Events &amp; Callbacks</h2>
<p>In the example of the vanilla JavaScript alert one could simply place a line of code after the <code>alert()</code> function in order to “tell” the server whether the button on the alert had been clicked. This was feasible because <code>alert</code> stops the execution of code, this is, however, rather uncommon in JavaScript. What is far more used are events and callback functions which are triggered upon an action is performed by the user (like the click of a button) or when other interesting things happen in the code. <a href="https://stephanwagner.me/jBox/options#events">jBox provides numerous such events</a>: callback functions can be used when a modal is closed or when it is created for instance.</p>
<p>The concept of the callback function is not totally foreign to R albeit rarely used. Shiny comes with such functions, e.g.: <code>shiny::onStop</code>. This allows having a function be triggered when the application exits (useful to close database connections for instance).</p>
<div class="sourceCode" id="cb138"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb138-1"><a href="shiny-1.html#cb138-1"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output){</span>
<span id="cb138-2"><a href="shiny-1.html#cb138-2"></a>  shiny<span class="op">::</span><span class="kw">onStop</span>(</span>
<span id="cb138-3"><a href="shiny-1.html#cb138-3"></a>    <span class="co"># callback function fired when app is closed</span></span>
<span id="cb138-4"><a href="shiny-1.html#cb138-4"></a>    <span class="cf">function</span>(){</span>
<span id="cb138-5"><a href="shiny-1.html#cb138-5"></a>      <span class="kw">cat</span>(<span class="st">&quot;App has been closed&quot;</span>)</span>
<span id="cb138-6"><a href="shiny-1.html#cb138-6"></a>    } <span class="cf">for</span> instance</span>
<span id="cb138-7"><a href="shiny-1.html#cb138-7"></a>  )</span>
<span id="cb138-8"><a href="shiny-1.html#cb138-8"></a>}</span></code></pre></div>
<p>In jBox, these callback functions are included in the JSON of options, below the <code>onClose</code> event is fired when the notice is closed.</p>
<div class="sourceCode" id="cb139"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb139-1"><a href="shiny-1.html#cb139-1"></a><span class="op">{</span></span>
<span id="cb139-2"><a href="shiny-1.html#cb139-2"></a>  <span class="dt">content</span><span class="op">:</span> <span class="st">&#39;Alert!&#39;</span><span class="op">,</span></span>
<span id="cb139-3"><a href="shiny-1.html#cb139-3"></a>  <span class="dt">onClose</span><span class="op">:</span> <span class="kw">function</span>()<span class="op">{</span></span>
<span id="cb139-4"><a href="shiny-1.html#cb139-4"></a>    <span class="co">// Fired when closed </span></span>
<span id="cb139-5"><a href="shiny-1.html#cb139-5"></a>    <span class="va">console</span>.<span class="at">log</span>(<span class="st">&#39;Alert is closed&#39;</span>)<span class="op">;</span></span>
<span id="cb139-6"><a href="shiny-1.html#cb139-6"></a>  <span class="op">}</span></span>
<span id="cb139-7"><a href="shiny-1.html#cb139-7"></a><span class="op">}</span></span></code></pre></div>
<p>This raises one issue, one cannot truly serialise an object of type function (there are exceptions later in the book).</p>
<div class="sourceCode" id="cb140"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb140-1"><a href="shiny-1.html#cb140-1"></a><span class="co"># try to serialise an R function</span></span>
<span id="cb140-2"><a href="shiny-1.html#cb140-2"></a>jsonlite<span class="op">::</span><span class="kw">toJSON</span>(<span class="cf">function</span>(x){x <span class="op">+</span><span class="st"> </span><span class="dv">1</span>})</span></code></pre></div>
<pre><code>## [&quot;function (x) &quot;,&quot;{&quot;,&quot;    x + 1&quot;,&quot;}&quot;]</code></pre>
<p>One solution is to append the callback function to the object of options JavaScript-side.</p>
<div class="sourceCode" id="cb142"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb142-1"><a href="shiny-1.html#cb142-1"></a>tags<span class="op">$</span><span class="kw">script</span>(<span class="st">&quot;Shiny.addCustomMessageHandler(type = &#39;send-alert&#39;, function(message) {</span></span>
<span id="cb142-2"><a href="shiny-1.html#cb142-2"></a><span class="st">  // append callback</span></span>
<span id="cb142-3"><a href="shiny-1.html#cb142-3"></a><span class="st">  message.onClose = function(){</span></span>
<span id="cb142-4"><a href="shiny-1.html#cb142-4"></a><span class="st">    Shiny.setInputValue(&#39;alert_close&#39;, true);</span></span>
<span id="cb142-5"><a href="shiny-1.html#cb142-5"></a><span class="st">  }</span></span>
<span id="cb142-6"><a href="shiny-1.html#cb142-6"></a><span class="st">  new jBox(&#39;Notice&#39;, message);</span></span>
<span id="cb142-7"><a href="shiny-1.html#cb142-7"></a><span class="st">});&quot;</span>)</span></code></pre></div>
<p>Placing a function inside a JSON object is common in JavaScript, in contrast with R where though it works is rarely if ever done (outside of reference class/R6). The above JavaScript code to append the callback function could look something like the snippet below in R.</p>
<div class="sourceCode" id="cb143"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb143-1"><a href="shiny-1.html#cb143-1"></a>message &lt;-<span class="st"> </span><span class="kw">list</span>(<span class="dt">content =</span> <span class="st">&quot;hello&quot;</span>)</span>
<span id="cb143-2"><a href="shiny-1.html#cb143-2"></a>message<span class="op">$</span>onClose &lt;-<span class="st"> </span><span class="cf">function</span>(x){</span>
<span id="cb143-3"><a href="shiny-1.html#cb143-3"></a>  x <span class="op">+</span><span class="st"> </span><span class="dv">1</span></span>
<span id="cb143-4"><a href="shiny-1.html#cb143-4"></a>}</span>
<span id="cb143-5"><a href="shiny-1.html#cb143-5"></a></span>
<span id="cb143-6"><a href="shiny-1.html#cb143-6"></a>message<span class="op">$</span><span class="kw">onClose</span>(<span class="dv">2</span>)</span></code></pre></div>
<pre><code>## [1] 3</code></pre>
<p>That done it can be incorporated into the application built thus far. Something interesting could be done server-side but for the sake of this example we merely print the value of the input to the R console.</p>
<div class="sourceCode" id="cb145"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb145-1"><a href="shiny-1.html#cb145-1"></a><span class="kw">library</span>(shiny)</span>
<span id="cb145-2"><a href="shiny-1.html#cb145-2"></a></span>
<span id="cb145-3"><a href="shiny-1.html#cb145-3"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb145-4"><a href="shiny-1.html#cb145-4"></a>  tags<span class="op">$</span><span class="kw">head</span>(</span>
<span id="cb145-5"><a href="shiny-1.html#cb145-5"></a>    tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb145-6"><a href="shiny-1.html#cb145-6"></a>      <span class="dt">src =</span> <span class="st">&quot;https://cdn.jsdelivr.net/gh/StephanWagner/jBox@v1.2.0/dist/jBox.all.min.js&quot;</span></span>
<span id="cb145-7"><a href="shiny-1.html#cb145-7"></a>    ),</span>
<span id="cb145-8"><a href="shiny-1.html#cb145-8"></a>    tags<span class="op">$</span><span class="kw">link</span>(</span>
<span id="cb145-9"><a href="shiny-1.html#cb145-9"></a>      <span class="dt">rel =</span> <span class="st">&quot;stylesheet&quot;</span>,</span>
<span id="cb145-10"><a href="shiny-1.html#cb145-10"></a>      <span class="dt">href =</span> <span class="st">&quot;https://cdn.jsdelivr.net/gh/StephanWagner/jBox@v1.2.0/dist/jBox.all.min.css&quot;</span></span>
<span id="cb145-11"><a href="shiny-1.html#cb145-11"></a>    ),</span>
<span id="cb145-12"><a href="shiny-1.html#cb145-12"></a>    tags<span class="op">$</span><span class="kw">script</span>(<span class="st">&quot;Shiny.addCustomMessageHandler(type = &#39;send-alert&#39;, function(message) {</span></span>
<span id="cb145-13"><a href="shiny-1.html#cb145-13"></a><span class="st">      message.onClose = function(){</span></span>
<span id="cb145-14"><a href="shiny-1.html#cb145-14"></a><span class="st">        Shiny.setInputValue(&#39;alert_close&#39;, true);</span></span>
<span id="cb145-15"><a href="shiny-1.html#cb145-15"></a><span class="st">      }</span></span>
<span id="cb145-16"><a href="shiny-1.html#cb145-16"></a><span class="st">      new jBox(&#39;Notice&#39;, message);</span></span>
<span id="cb145-17"><a href="shiny-1.html#cb145-17"></a><span class="st">    });&quot;</span>)</span>
<span id="cb145-18"><a href="shiny-1.html#cb145-18"></a>  )</span>
<span id="cb145-19"><a href="shiny-1.html#cb145-19"></a>)</span>
<span id="cb145-20"><a href="shiny-1.html#cb145-20"></a></span>
<span id="cb145-21"><a href="shiny-1.html#cb145-21"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session){</span>
<span id="cb145-22"><a href="shiny-1.html#cb145-22"></a></span>
<span id="cb145-23"><a href="shiny-1.html#cb145-23"></a>  <span class="co"># define notice options</span></span>
<span id="cb145-24"><a href="shiny-1.html#cb145-24"></a>  notice =<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb145-25"><a href="shiny-1.html#cb145-25"></a>    <span class="dt">content =</span> <span class="st">&#39;Hello from the server&#39;</span>,</span>
<span id="cb145-26"><a href="shiny-1.html#cb145-26"></a>    <span class="dt">color =</span> <span class="st">&#39;black&#39;</span></span>
<span id="cb145-27"><a href="shiny-1.html#cb145-27"></a>  )</span>
<span id="cb145-28"><a href="shiny-1.html#cb145-28"></a></span>
<span id="cb145-29"><a href="shiny-1.html#cb145-29"></a>  <span class="co"># send the notice</span></span>
<span id="cb145-30"><a href="shiny-1.html#cb145-30"></a>  session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="dt">type =</span> <span class="st">&quot;send-alert&quot;</span>, <span class="dt">message =</span> notice)</span>
<span id="cb145-31"><a href="shiny-1.html#cb145-31"></a></span>
<span id="cb145-32"><a href="shiny-1.html#cb145-32"></a>  <span class="co"># print the output of the alert_close event (when fired)</span></span>
<span id="cb145-33"><a href="shiny-1.html#cb145-33"></a>  <span class="kw">observeEvent</span>(input<span class="op">$</span>alert_close, {</span>
<span id="cb145-34"><a href="shiny-1.html#cb145-34"></a>    <span class="kw">print</span>(input<span class="op">$</span>alert_close)</span>
<span id="cb145-35"><a href="shiny-1.html#cb145-35"></a>  })</span>
<span id="cb145-36"><a href="shiny-1.html#cb145-36"></a>}</span>
<span id="cb145-37"><a href="shiny-1.html#cb145-37"></a></span>
<span id="cb145-38"><a href="shiny-1.html#cb145-38"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
</div>
<div id="as-a-package" class="section level2 unnumbered" number="">
<h2>As a Package</h2>
<p><em>If confused by any of the following please visit the <a href="package-development">package development section</a> in the first chapter.</em></p>
<p>Packages are a fundamental part of R and allow conveniently sharing and reusing code. The work done so far is probably fitting for a single application but one should not have to reproduce all of that every time one wants to use jBox in a shiny application: we ought to wrap these functionalities into a handy package that can be used, reused and shared with others. Moreover, this will benefit from all the other advantages that R packages bring to code such as documentation, reproducibility, and tests.</p>
<p>Before we delve into building the package let us think through what it should include. The application using jBox gives some indication as to what the package will look like. Users of the package should be able to reproduce what is executed in the application, namely import dependencies (including the message handler) as well as send data to the JavaScript front-end. Finally, we shall provide, with the package, a static directory of dependencies to avoid relying on the CDNs as this ensures reproducibility (code hosted online by third-party might change and break the package). Concretely, the package will export a <code>useJbox</code> function to be placed in the shiny ui to import the dependencies (essentially replacing the <code>tags$*</code>) and a function to send the alert from the server to the client.</p>
<p>Let’s start by creating an R package, here we name it “jbox,” after the JavaScript of the same name, partly because the author lacks creativity: feel free to name it however you want.</p>
<div class="sourceCode" id="cb146"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb146-1"><a href="shiny-1.html#cb146-1"></a>usethis<span class="op">::</span><span class="kw">create_package</span>(<span class="st">&quot;jbox&quot;</span>)</span></code></pre></div>
<div id="dependencies" class="section level3 unnumbered" number="">
<h3>Dependencies</h3>
<p><em>If confused by any of the following please visit the <a href="shiny-1.html#static-files">static files section</a> of this chapter.</em></p>
<p>The very first thing that is required are the dependencies without which nothing can work, let’s create a directory of static assets, download and place the jBox CSS and JavaScript files within it. We create the directory “inst” as per the R package convention and within it create another to hold our assets.</p>
<div class="sourceCode" id="cb147"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb147-1"><a href="shiny-1.html#cb147-1"></a><span class="co"># create directories</span></span>
<span id="cb147-2"><a href="shiny-1.html#cb147-2"></a><span class="kw">dir.create</span>(<span class="st">&quot;inst/assets&quot;</span>, <span class="dt">recursive =</span> <span class="ot">TRUE</span>)</span></code></pre></div>
<p>The jBox files can be downloaded from the CDN and placed within the directory that was created above. Moreover, we also create an empty JavaScript file that will eventually contain the custom JavaScript code that “connects” R to JavaScript.</p>
<div class="sourceCode" id="cb148"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb148-1"><a href="shiny-1.html#cb148-1"></a><span class="co"># URLs of CDNs</span></span>
<span id="cb148-2"><a href="shiny-1.html#cb148-2"></a>js_dep &lt;-<span class="st"> &quot;https://cdn.jsdelivr.net/gh/StephanWagner/jBox@v1.2.0/dist/jBox.all.min.js&quot;</span></span>
<span id="cb148-3"><a href="shiny-1.html#cb148-3"></a>css_dep &lt;-<span class="st"> &quot;https://cdn.jsdelivr.net/gh/StephanWagner/jBox@v1.2.0/dist/jBox.all.min.css&quot;</span></span>
<span id="cb148-4"><a href="shiny-1.html#cb148-4"></a></span>
<span id="cb148-5"><a href="shiny-1.html#cb148-5"></a><span class="co"># download</span></span>
<span id="cb148-6"><a href="shiny-1.html#cb148-6"></a><span class="kw">download.file</span>(js_dep, <span class="dt">destfile =</span> <span class="st">&quot;./inst/assets/jBox.all.min.js&quot;</span>)</span>
<span id="cb148-7"><a href="shiny-1.html#cb148-7"></a><span class="kw">download.file</span>(css_dep, <span class="dt">destfile =</span> <span class="st">&quot;./inst/assets/jBox.all.min.css&quot;</span>)</span>
<span id="cb148-8"><a href="shiny-1.html#cb148-8"></a></span>
<span id="cb148-9"><a href="shiny-1.html#cb148-9"></a><span class="co"># create file to eventually hold custom JavaScript</span></span>
<span id="cb148-10"><a href="shiny-1.html#cb148-10"></a><span class="kw">file.create</span>(<span class="st">&quot;./inst/assets/custom.js&quot;</span>)</span></code></pre></div>
<p>This done one should obtain a directory that looks similar to the tree below (some files and folders omitted for brevity).</p>
<div class="sourceCode" id="cb149"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb149-1"><a href="shiny-1.html#cb149-1"></a><span class="ex">DESCRIPTION</span></span>
<span id="cb149-2"><a href="shiny-1.html#cb149-2"></a><span class="ex">R/</span></span>
<span id="cb149-3"><a href="shiny-1.html#cb149-3"></a><span class="ex">inst/</span></span>
<span id="cb149-4"><a href="shiny-1.html#cb149-4"></a>├── <span class="ex">assets/</span></span>
<span id="cb149-5"><a href="shiny-1.html#cb149-5"></a>│    ├── <span class="ex">jBox.all.min.js</span></span>
<span id="cb149-6"><a href="shiny-1.html#cb149-6"></a>│    └── <span class="ex">jBox.all.min.css</span></span></code></pre></div>
<p>Next, one needs to have those files served, the user of the package could be asked to use <code>shiny::addResourcePath</code> but it’s very inelegant, this should be built-in the package so the user does not even have to know this happening in the background. Therefore, we ought to ensure the static files are served when the user uses the package. Packages can optionally run functions when it is loaded or attached, Hadley Wickham writes about it extensively in the namespace chapter of his <a href="http://r-pkgs.had.co.nz/namespace.html">book on R packages</a>. By convention, these functions are placed in a <code>zzz.R</code> file.</p>
<div class="sourceCode" id="cb150"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb150-1"><a href="shiny-1.html#cb150-1"></a><span class="kw">file.create</span>(<span class="st">&quot;./R/zzz.R&quot;</span>)</span></code></pre></div>
<p>The difference between loading and attaching a package can be subtle, in this case it’s probably best to run the function when the package is loaded using <code>onLoad</code> which the R Packages book describes as:</p>
<blockquote>
<p>Loading will load code, data and any DLLs; register S3 and S4 methods; and run the .onLoad() function. After loading, the package is available in memory, but because it’s not in the search path, you won’t be able to access its components without using ::. Confusingly, :: will also load a package automatically if it isn’t already loaded. It’s rare to load a package explicitly, but you can do so with requireNamespace() or loadNamespace().</p>
</blockquote>
<p>The <code>addResourcePath</code> function should thus be placed within the <code>.onLoad</code> function, this way the files are served by shiny when the package is loaded. Note the few changes below, we refer to the path using <code>system.file</code> (detailed in the <a href="introduction.html#package-development">Package Development section</a>) and change the the prefix to <code>jbox-assets</code> to avoid the url serving our static files to clash with others.</p>
<div class="sourceCode" id="cb151"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb151-1"><a href="shiny-1.html#cb151-1"></a><span class="co"># R/zzz.R</span></span>
<span id="cb151-2"><a href="shiny-1.html#cb151-2"></a>.onLoad &lt;-<span class="st"> </span><span class="cf">function</span>(libname, pkgname) {</span>
<span id="cb151-3"><a href="shiny-1.html#cb151-3"></a>  shiny<span class="op">::</span><span class="kw">addResourcePath</span>(</span>
<span id="cb151-4"><a href="shiny-1.html#cb151-4"></a>    <span class="st">&quot;jbox-assets&quot;</span>,</span>
<span id="cb151-5"><a href="shiny-1.html#cb151-5"></a>    <span class="kw">system.file</span>(<span class="st">&quot;assets&quot;</span>, <span class="dt">package =</span> <span class="st">&quot;jbox&quot;</span>)</span>
<span id="cb151-6"><a href="shiny-1.html#cb151-6"></a>  )</span>
<span id="cb151-7"><a href="shiny-1.html#cb151-7"></a>}</span></code></pre></div>
<p>This serves the file and allows not having to explicitly use <code>addResourcePath</code> but the package nonetheless needs to feature a function to let the user import them into their application.</p>
<div class="sourceCode" id="cb152"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb152-1"><a href="shiny-1.html#cb152-1"></a><span class="co">#&#39; Import Dependencies</span></span>
<span id="cb152-2"><a href="shiny-1.html#cb152-2"></a><span class="co">#&#39; @export</span></span>
<span id="cb152-3"><a href="shiny-1.html#cb152-3"></a>usejBox &lt;-<span class="st"> </span><span class="cf">function</span>(){</span>
<span id="cb152-4"><a href="shiny-1.html#cb152-4"></a>  shiny<span class="op">::</span>tags<span class="op">$</span><span class="kw">head</span>(</span>
<span id="cb152-5"><a href="shiny-1.html#cb152-5"></a>    shiny<span class="op">::</span>tags<span class="op">$</span><span class="kw">script</span>(<span class="dt">src =</span> <span class="st">&quot;jbox-assets/jBox.all.min.js&quot;</span>),</span>
<span id="cb152-6"><a href="shiny-1.html#cb152-6"></a>    shiny<span class="op">::</span>tags<span class="op">$</span><span class="kw">link</span>(<span class="dt">rel =</span> <span class="st">&quot;stylesheet&quot;</span>, <span class="dt">href =</span> <span class="st">&quot;jbox-assets/jBox.all.min.css&quot;</span>),</span>
<span id="cb152-7"><a href="shiny-1.html#cb152-7"></a>    shiny<span class="op">::</span>tags<span class="op">$</span><span class="kw">script</span>(<span class="dt">src =</span> <span class="st">&quot;jbox-assets/custom.js&quot;</span>)</span>
<span id="cb152-8"><a href="shiny-1.html#cb152-8"></a>  )</span>
<span id="cb152-9"><a href="shiny-1.html#cb152-9"></a>}</span></code></pre></div>
<p>Users of the package can place the function defined above in the UI of their application to import the dependencies.</p>
</div>
<div id="r-code" class="section level3 unnumbered" number="">
<h3>R Code</h3>
<p>Not much changes from what was written before, however, it poses interesting questions with regard to the interface we want to provide users. From the user’s perspective the core of the package is the function that actually sends an alert to the clients, here created in <code>R/core.R</code>.</p>
<div class="sourceCode" id="cb153"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb153-1"><a href="shiny-1.html#cb153-1"></a><span class="co">#&#39; Create an Alert</span></span>
<span id="cb153-2"><a href="shiny-1.html#cb153-2"></a><span class="co">#&#39; @export</span></span>
<span id="cb153-3"><a href="shiny-1.html#cb153-3"></a>send_alert &lt;-<span class="st"> </span><span class="cf">function</span>(<span class="dt">content =</span> <span class="st">&quot;alert&quot;</span>, <span class="dt">color =</span> <span class="st">&quot;blue&quot;</span>, session){</span>
<span id="cb153-4"><a href="shiny-1.html#cb153-4"></a>  <span class="co"># define notice options</span></span>
<span id="cb153-5"><a href="shiny-1.html#cb153-5"></a>  notice =<span class="st"> </span><span class="kw">list</span>(<span class="dt">content =</span> content, <span class="dt">color =</span> <span class="st">&quot;black&quot;</span>)</span>
<span id="cb153-6"><a href="shiny-1.html#cb153-6"></a></span>
<span id="cb153-7"><a href="shiny-1.html#cb153-7"></a>  <span class="co"># send the notice</span></span>
<span id="cb153-8"><a href="shiny-1.html#cb153-8"></a>  session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="dt">type =</span> <span class="st">&quot;send-alert&quot;</span>, <span class="dt">message =</span> notice)</span>
<span id="cb153-9"><a href="shiny-1.html#cb153-9"></a>}</span></code></pre></div>
<p>One could leave it at the function above, it could be sufficient in providing a functional R package. However one could improve somewhat on it, currently, the function requires the <code>session</code> object, which confuses many, most R developers, including I, have little understanding of it. This can be mitigated by providing a default using <code>shiny::getDefaultReactiveDomain</code> which, notwithstanding its grandiose name, simply returns the shiny <code>session</code>. This means that function has be run from a shiny server function but that is no limitation in this case.</p>
<div class="sourceCode" id="cb154"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb154-1"><a href="shiny-1.html#cb154-1"></a><span class="co">#&#39; Create an Alert</span></span>
<span id="cb154-2"><a href="shiny-1.html#cb154-2"></a><span class="co">#&#39; @export</span></span>
<span id="cb154-3"><a href="shiny-1.html#cb154-3"></a>send_alert &lt;-<span class="st"> </span><span class="cf">function</span>(<span class="dt">content =</span> <span class="st">&quot;alert&quot;</span>, <span class="dt">color =</span> <span class="st">&quot;blue&quot;</span>, <span class="dt">session =</span> shiny<span class="op">::</span><span class="kw">getDefaultReactiveDomain</span>()){</span>
<span id="cb154-4"><a href="shiny-1.html#cb154-4"></a>  <span class="co"># define notice options</span></span>
<span id="cb154-5"><a href="shiny-1.html#cb154-5"></a>  notice =<span class="st"> </span><span class="kw">list</span>(<span class="dt">content =</span> content, <span class="dt">color =</span> <span class="st">&quot;black&quot;</span>)</span>
<span id="cb154-6"><a href="shiny-1.html#cb154-6"></a></span>
<span id="cb154-7"><a href="shiny-1.html#cb154-7"></a>  <span class="co"># send the notice</span></span>
<span id="cb154-8"><a href="shiny-1.html#cb154-8"></a>  session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="dt">type =</span> <span class="st">&quot;send-alert&quot;</span>, <span class="dt">message =</span> notice)</span>
<span id="cb154-9"><a href="shiny-1.html#cb154-9"></a>}</span></code></pre></div>
<p>This covers most of the R code that needs to be written, though we will come back to it shortly on as we uncover an interesting caveat.</p>
</div>
<div id="javascript-code" class="section level3 unnumbered" number="">
<h3>JavaScript Code</h3>
<p>Onto the JavaScript code, the <code>custom.js</code> to host said code is already created but remains empty. Simply using the code that was written previously will do the job for now.</p>
<div class="sourceCode" id="cb155"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb155-1"><a href="shiny-1.html#cb155-1"></a><span class="co">// custom.js</span></span>
<span id="cb155-2"><a href="shiny-1.html#cb155-2"></a><span class="va">Shiny</span>.<span class="at">addCustomMessageHandler</span>(type <span class="op">=</span> <span class="st">&#39;send-alert&#39;</span><span class="op">,</span> <span class="kw">function</span>(message) <span class="op">{</span></span>
<span id="cb155-3"><a href="shiny-1.html#cb155-3"></a>  <span class="va">message</span>.<span class="at">onClose</span> <span class="op">=</span> <span class="kw">function</span>()<span class="op">{</span></span>
<span id="cb155-4"><a href="shiny-1.html#cb155-4"></a>    <span class="va">Shiny</span>.<span class="at">setInputValue</span>(<span class="st">&#39;alert_close&#39;</span><span class="op">,</span> <span class="kw">true</span>)<span class="op">;</span></span>
<span id="cb155-5"><a href="shiny-1.html#cb155-5"></a>  <span class="op">}</span></span>
<span id="cb155-6"><a href="shiny-1.html#cb155-6"></a>  <span class="kw">new</span> <span class="at">jBox</span>(<span class="st">&#39;Notice&#39;</span><span class="op">,</span> message)<span class="op">;</span></span>
<span id="cb155-7"><a href="shiny-1.html#cb155-7"></a><span class="op">}</span>)<span class="op">;</span></span></code></pre></div>
</div>
<div id="shortcoming" class="section level3 unnumbered" number="">
<h3>Shortcoming</h3>
<p>At this stage one has a fully functional package: document, load the functions, and it can be used.</p>
<div class="sourceCode" id="cb156"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb156-1"><a href="shiny-1.html#cb156-1"></a>devtools<span class="op">::</span><span class="kw">document</span>()</span>
<span id="cb156-2"><a href="shiny-1.html#cb156-2"></a>devtools<span class="op">::</span><span class="kw">load_all</span>()</span>
<span id="cb156-3"><a href="shiny-1.html#cb156-3"></a></span>
<span id="cb156-4"><a href="shiny-1.html#cb156-4"></a><span class="kw">library</span>(shiny)</span>
<span id="cb156-5"><a href="shiny-1.html#cb156-5"></a></span>
<span id="cb156-6"><a href="shiny-1.html#cb156-6"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb156-7"><a href="shiny-1.html#cb156-7"></a>  <span class="kw">usejBox</span>(),</span>
<span id="cb156-8"><a href="shiny-1.html#cb156-8"></a>  <span class="kw">verbatimTextOutput</span>(<span class="st">&quot;callback&quot;</span>)</span>
<span id="cb156-9"><a href="shiny-1.html#cb156-9"></a>)</span>
<span id="cb156-10"><a href="shiny-1.html#cb156-10"></a></span>
<span id="cb156-11"><a href="shiny-1.html#cb156-11"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output){</span>
<span id="cb156-12"><a href="shiny-1.html#cb156-12"></a>  <span class="kw">send_alert</span>(<span class="st">&quot;Hello from the server!&quot;</span>)</span>
<span id="cb156-13"><a href="shiny-1.html#cb156-13"></a></span>
<span id="cb156-14"><a href="shiny-1.html#cb156-14"></a>  output<span class="op">$</span>callback &lt;-<span class="st"> </span><span class="kw">renderPrint</span>({</span>
<span id="cb156-15"><a href="shiny-1.html#cb156-15"></a>    <span class="kw">paste</span>(<span class="st">&quot;Is the alert closed: &quot;</span>, input<span class="op">$</span>alert_close)</span>
<span id="cb156-16"><a href="shiny-1.html#cb156-16"></a>  })</span>
<span id="cb156-17"><a href="shiny-1.html#cb156-17"></a>}</span>
<span id="cb156-18"><a href="shiny-1.html#cb156-18"></a></span>
<span id="cb156-19"><a href="shiny-1.html#cb156-19"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<p>However, while the above will work for a single alert it will run into issues when creating more than one alert as multiple alerts will set a value for a single input (<code>input$alert_close</code>). This is can be remedied to.</p>
</div>
<div id="input" class="section level3 unnumbered" number="">
<h3>Input</h3>
<p>The package needs to provide the user a way to distinguish between alerts in order to be able to observe the correct inputs server-side.
A simple solution consists in asking the user to provide an identifier (<code>id</code>). This identifier must be passed to the JavaScript client so the function can dynamically set the input value for that identifier, therefore it is included in the <code>message</code>, below we do so in such a way that the original JSON of options remains unchanged.</p>
<div class="sourceCode" id="cb157"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb157-1"><a href="shiny-1.html#cb157-1"></a><span class="co">#&#39; Create an Alert</span></span>
<span id="cb157-2"><a href="shiny-1.html#cb157-2"></a><span class="co">#&#39; @export</span></span>
<span id="cb157-3"><a href="shiny-1.html#cb157-3"></a>send_alert &lt;-<span class="st"> </span><span class="cf">function</span>(id, <span class="dt">content =</span> <span class="st">&quot;alert&quot;</span>, <span class="dt">color =</span> <span class="st">&quot;blue&quot;</span>, <span class="dt">session =</span> shiny<span class="op">::</span><span class="kw">getDefaultReactiveDomain</span>()){</span>
<span id="cb157-4"><a href="shiny-1.html#cb157-4"></a>  <span class="co"># define notice options</span></span>
<span id="cb157-5"><a href="shiny-1.html#cb157-5"></a>  notice =<span class="st"> </span><span class="kw">list</span>(<span class="dt">content =</span> content, <span class="dt">color =</span> <span class="st">&quot;black&quot;</span>)</span>
<span id="cb157-6"><a href="shiny-1.html#cb157-6"></a></span>
<span id="cb157-7"><a href="shiny-1.html#cb157-7"></a>  <span class="co"># add id</span></span>
<span id="cb157-8"><a href="shiny-1.html#cb157-8"></a>  message &lt;-<span class="st"> </span><span class="kw">list</span>(<span class="dt">id =</span> id, <span class="dt">notice =</span> notice)</span>
<span id="cb157-9"><a href="shiny-1.html#cb157-9"></a></span>
<span id="cb157-10"><a href="shiny-1.html#cb157-10"></a>  <span class="co"># send the notice</span></span>
<span id="cb157-11"><a href="shiny-1.html#cb157-11"></a>  session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="dt">type =</span> <span class="st">&quot;send-alert&quot;</span>, <span class="dt">message =</span> message)</span>
<span id="cb157-12"><a href="shiny-1.html#cb157-12"></a>}</span></code></pre></div>
<p>Now one can adapt the JavaScript code to make use of the identifier. One needs to include said identifier in the name of the input the value of which is set, below we concatenate before the original input name. This is not forced upon the developer but is a convention, packages like DT and plotly approach the issue the same way: <code>id + name_of_input</code>. The event is thus now appended to <code>message.notice</code>, which is also used when creating the jBox alert.</p>
<div class="sourceCode" id="cb158"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb158-1"><a href="shiny-1.html#cb158-1"></a><span class="co">// custom.js</span></span>
<span id="cb158-2"><a href="shiny-1.html#cb158-2"></a><span class="va">Shiny</span>.<span class="at">addCustomMessageHandler</span>(type <span class="op">=</span> <span class="st">&#39;send-alert&#39;</span><span class="op">,</span> <span class="kw">function</span>(message) <span class="op">{</span></span>
<span id="cb158-3"><a href="shiny-1.html#cb158-3"></a>  <span class="va">message</span>.<span class="va">notice</span>.<span class="at">onClose</span> <span class="op">=</span> <span class="kw">function</span>()<span class="op">{</span></span>
<span id="cb158-4"><a href="shiny-1.html#cb158-4"></a>    <span class="va">console</span>.<span class="at">log</span>(<span class="st">&quot;close&quot;</span>)<span class="op">;</span></span>
<span id="cb158-5"><a href="shiny-1.html#cb158-5"></a>    <span class="va">Shiny</span>.<span class="at">setInputValue</span>(<span class="va">message</span>.<span class="at">id</span> <span class="op">+</span> <span class="st">&#39;_alert_close&#39;</span><span class="op">,</span> <span class="kw">true</span>)<span class="op">;</span></span>
<span id="cb158-6"><a href="shiny-1.html#cb158-6"></a>  <span class="op">}</span></span>
<span id="cb158-7"><a href="shiny-1.html#cb158-7"></a>  <span class="kw">new</span> <span class="at">jBox</span>(<span class="st">&#39;Notice&#39;</span><span class="op">,</span> <span class="va">message</span>.<span class="at">notice</span>)<span class="op">;</span></span>
<span id="cb158-8"><a href="shiny-1.html#cb158-8"></a><span class="op">}</span>)<span class="op">;</span></span></code></pre></div>
</div>
<div id="wrapping-up" class="section level3 unnumbered" number="">
<h3>Wrapping up</h3>
<p>Building and installing the package will now provide the user an interface demonstrated below.</p>
<div class="sourceCode" id="cb159"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb159-1"><a href="shiny-1.html#cb159-1"></a><span class="kw">library</span>(jbox)</span>
<span id="cb159-2"><a href="shiny-1.html#cb159-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb159-3"><a href="shiny-1.html#cb159-3"></a></span>
<span id="cb159-4"><a href="shiny-1.html#cb159-4"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb159-5"><a href="shiny-1.html#cb159-5"></a>  <span class="kw">usejBox</span>(),</span>
<span id="cb159-6"><a href="shiny-1.html#cb159-6"></a>  <span class="kw">verbatimTextOutput</span>(<span class="st">&quot;callback&quot;</span>)</span>
<span id="cb159-7"><a href="shiny-1.html#cb159-7"></a>)</span>
<span id="cb159-8"><a href="shiny-1.html#cb159-8"></a></span>
<span id="cb159-9"><a href="shiny-1.html#cb159-9"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output){</span>
<span id="cb159-10"><a href="shiny-1.html#cb159-10"></a>  <span class="kw">send_alert</span>(<span class="st">&quot;myid&quot;</span>, <span class="st">&quot;Hello from the server!&quot;</span>)</span>
<span id="cb159-11"><a href="shiny-1.html#cb159-11"></a></span>
<span id="cb159-12"><a href="shiny-1.html#cb159-12"></a>  output<span class="op">$</span>callback &lt;-<span class="st"> </span><span class="kw">renderPrint</span>({</span>
<span id="cb159-13"><a href="shiny-1.html#cb159-13"></a>    <span class="kw">paste</span>(<span class="st">&quot;Is the alert closed: &quot;</span>, input<span class="op">$</span>myid_alert_close)</span>
<span id="cb159-14"><a href="shiny-1.html#cb159-14"></a>  })</span>
<span id="cb159-15"><a href="shiny-1.html#cb159-15"></a>}</span>
<span id="cb159-16"><a href="shiny-1.html#cb159-16"></a></span>
<span id="cb159-17"><a href="shiny-1.html#cb159-17"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<p>It must be noted that though the package will be fully functional it will not pass any checks as documentation is poor and the DESCRIPTION incomplete. The API provided to the user is probably subpar in places, namely with the use of the id, which, unless the user needs to observe the respective input, is not necessary: forcing the user to provide it is not great design, consider making this optional.</p>
</div>
</div>
<div id="exercises" class="section level2 unnumbered" number="">
<h2>Exercises</h2>
<p>If one wants to create such packages or make extensive use of such integrations with Shiny, it is greatly encouraged to explore it further, namely by improving the API constructed and extending the functionalities (jBox comes with much more than just alerts), even integrate a JavaScript of your choice. At the time of writing this there is not package providing integration with jBox, if that is not of interest to the reader below are some other great libraries that are yet to be packaged in R and would greatly benefit the R community:</p>
<ul>
<li><a href="https://github.com/Ghosh/micromodal">micromodal.js</a> - tiny, dependency-free javascript library for creating accessible modal dialogs</li>
<li><a href="https://github.com/jaywcjlove/hotkeys">hotkeys</a> - Capturing keyboard inputs</li>
<li><a href="https://github.com/victordibia/handtrack.js">handtrack.js</a> - realtime hand detection</li>
<li><a href="https://github.com/skt-t1-byungi/rsup-progress">Rsup-progress</a> - simple progress bars</li>
</ul>

</div>
</div>



<h3>References</h3>
<div id="refs" class="references">
<div id="ref-R-shinyjs">
<p>Attali, Dean. 2020. <em>Shinyjs: Easily Improve the User Experience of Your Shiny Apps in Seconds</em>. <a href="https://CRAN.R-project.org/package=shinyjs">https://CRAN.R-project.org/package=shinyjs</a>.</p>
</div>
<div id="ref-R-waiter">
<p>Coene, John. 2020. <em>Waiter: Loading Screen for ’Shiny’</em>.</p>
</div>
<div id="ref-R-golem">
<p>Guyader, Vincent, Colin Fay, Sébastien Rochette, and Cervan Girard. 2020. <em>Golem: A Framework for Robust Shiny Applications</em>. <a href="https://CRAN.R-project.org/package=golem">https://CRAN.R-project.org/package=golem</a>.</p>
</div>
</div>
            </section>

          </div>
        </div>
      </div>
<a href="node.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="html-widgets.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
    </div>
  </div>
<script src="libs/gitbook/js/app.min.js"></script>
<script src="libs/gitbook/js/lunr.js"></script>
<script src="libs/gitbook/js/clipboard.min.js"></script>
<script src="libs/gitbook/js/plugin-search.js"></script>
<script src="libs/gitbook/js/plugin-sharing.js"></script>
<script src="libs/gitbook/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook/js/plugin-bookdown.js"></script>
<script src="libs/gitbook/js/jquery.highlight.js"></script>
<script src="libs/gitbook/js/plugin-clipboard.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": true,
"facebook": false,
"twitter": false,
"linkedin": false,
"weibo": false,
"instapaper": false,
"vk": false,
"all": {}
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": "https://github.com/JohnCoene/r-and-javascript/edit/master/04-Shiny.Rmd",
"text": "Edit"
},
"history": {
"link": null,
"text": null
},
"view": {
"link": null,
"text": null
},
"download": {},
"toc": {
"collapse": "section"
}
});
});
</script>

</body>

</html>
